<script setup>
import { ref, reactive, computed, nextTick } from 'vue'
import { ElMessageBox, ElMessage } from 'element-plus'
import {
  getRoleListAPI,
  getPermListAPI,
  getRolePermAPI,
  addRoleAPI,
  deleteRoleAPI,
  updateRoleAPI
} from '@/api/role'

const roleLoading = ref(false)
const activeIndex = ref(0)
const roleList = ref([])
// 获取角色列表
const getRoleList = async () => {
  roleLoading.value = true
  try {
    const res = await getRoleListAPI()
    roleList.value = res
    if (res.length > 0) {
      nextTick(() => {
        getRolePerm(treeRef, res[activeIndex.value].id)
      })
    }
  } finally {
    roleLoading.value = false
  }
}

// 权限
const treeLoading = ref(false)
const activeName = ref('tree')
const treeRef = ref(null)
const permList = ref([])
const rolePerms = ref([])
// 获取角色对应的权限列表
const getRolePerm = async (treeList, id) => {
  treeLoading.value = true
  try {
    const res = await getRolePermAPI(id)
    treeList.value.forEach((tree) => {
      tree.setCheckedKeys(res)
    })
    rolePerms.value = res
  } finally {
    treeLoading.value = false
  }
}
// 获取权限列表
const getPermList = async () => {
  const res = await getPermListAPI()
  permList.value = res
}
// 切换角色
const changeRole = async (index) => {
  if (activeIndex.value === index) return
  activeIndex.value = index
  getRolePerm(treeRef, roleList.value[index].id)
}

// 添加或编辑角色
const btnLoading = ref(false)
const showDrawer = ref(false)
const roleFormRef = ref(null)
const roleTreeRef = ref(null)
const roleForm = reactive({ id: null, name: '' })
const roleRules = { name: [{ required: true, message: '请输入角色名称', targer: 'blur' }] }

// 提交数据--添加/编辑角色
const handleSubmitRole = async () => {
  roleFormRef.value.validate(async (valid) => {
    if (!valid) return
    btnLoading.value = true
    try {
      // 获取选中的权限
      const ids = []
      roleTreeRef.value.forEach((tree) => {
        ids.push(...tree.getCheckedKeys())
      })
      if (!ids.length) return ElMessage.warning('请勾选权限信息！')
      if (roleForm.id) {
        await updateRoleAPI({ name: roleForm.name, rid: roleForm.id, pid: ids.join(',') })
      } else {
        await addRoleAPI({ name: roleForm.name, perms: ids.join(',') })
      }
      ElMessage.success(`${drawerTitle.value}成功`)
      showDrawer.value = false
      getRoleList()
    } finally {
      btnLoading.value = false
    }
  })
}
const drawerTitle = computed(() => (roleForm.id ? '编辑' : '添加'))

// 打开drawer
const openDrawer = (role) => {
  roleFormRef.value && roleFormRef.value.clearValidate()
  showDrawer.value = true
  if (role.id) {
    roleForm.id = role.id
    roleForm.name = role.role_name
    getRolePerm(roleTreeRef, role.id)
  }
}
// 关闭drawer回调
const handleClosed = () => {
  roleForm.name = ''
  roleForm.id = null
  setCheckedKeys([])
}
// 设置树形菜单选中
const setCheckedKeys = (arr) => {
  if (roleTreeRef.value) {
    roleTreeRef.value.forEach((tree) => {
      tree.setCheckedKeys(arr)
    })
  }
}

// 删除角色
const handleDelete = async (id) => {
  try {
    await ElMessageBox.confirm('确定要删除此条数据吗?', '温馨提示', { type: 'warning' })
    await deleteRoleAPI(id)
    ElMessage.success('删除成功')
    activeIndex.value = 0
    getRoleList()
  } catch (error) {}
}
// tree的配置
const defaultProps = {
  label: 'name',
  disabled: () => true
}
getRoleList()
getPermList()
</script>

<template>
  <layout-card>
    <div class="role-container">
      <!-- 左侧 -->
      <div v-loading="roleLoading" class="role-left">
        <div
          class="role-item"
          v-for="(item, index) in roleList"
          :key="item.id"
          :class="{ active: index === activeIndex }"
          @click="changeRole(index)"
        >
          <div class="role-info">
            <svg-icon
              icon-name="user"
              :class-name="index === activeIndex ? 'active-role' : ''"
              class="icon"
            />
            {{ item.role_name }}
          </div>
          <div class="more">
            <el-dropdown>
              <span class="el-dropdown-link">
                <svg-icon icon-name="more" />
              </span>
              <template #dropdown>
                <el-dropdown-menu>
                  <el-dropdown-item @click="openDrawer(item)">编辑</el-dropdown-item>
                  <el-dropdown-item @click="handleDelete(item.id)">删除</el-dropdown-item>
                </el-dropdown-menu>
              </template>
            </el-dropdown>
          </div>
        </div>
        <el-button v-permission="'role:list:createRole'" class="role-add" @click="openDrawer('')"
          >添加角色</el-button
        >
      </div>
      <!-- 右侧 -->
      <div class="role-right">
        <el-tabs v-model="activeName">
          <!-- 功能权限 -->
          <el-tab-pane label="功能权限" name="tree">
            <div v-loading="treeLoading" class="tree-list">
              <div v-for="item in permList" :key="item.id" class="tree-item">
                <div class="tree-title">{{ item.name }}</div>
                <el-tree
                  ref="treeRef"
                  :data="item.children"
                  node-key="id"
                  :props="defaultProps"
                  default-expand-all
                  show-checkbox
                />
              </div>
            </div>
          </el-tab-pane>
          <!-- 成员列表 -->
          <el-tab-pane label="成员列表" name="member">
            <div class="member-list">开发中...</div>
          </el-tab-pane>
        </el-tabs>
      </div>
    </div>
    <!-- 添加/编辑角色 -->
    <el-drawer v-model="showDrawer" :title="`${drawerTitle}角色`" size="65%" @closed="handleClosed">
      <div class="role-name">
        <el-form ref="roleFormRef" :model="roleForm" :rules="roleRules">
          <el-form-item label="角色名称" prop="name">
            <el-input v-model="roleForm.name" placeholder="请输入角色名称" style="width: 200px" />
          </el-form-item>
        </el-form>
      </div>
      <div class="tree-list">
        <div v-for="item in permList" :key="item.id" class="tree-item">
          <div class="tree-title">{{ item.name }}</div>
          <el-tree
            ref="roleTreeRef"
            :data="item.children"
            node-key="id"
            :props="{ label: 'name' }"
            default-expand-all
            show-checkbox
          />
        </div>
      </div>
      <template #footer>
        <div class="role-footer">
          <el-button :loading="btnLoading" type="primary" @click="handleSubmitRole">{{
            drawerTitle
          }}</el-button>
        </div>
      </template>
    </el-drawer>
  </layout-card>
</template>

<style lang="scss" scoped>
.role-container {
  display: flex;
  font-size: 14px;
}
.role-left {
  width: 200px;
  border-right: 1px solid #e4e7ec;
  padding: 4px;
  text-align: center;
  .role-item {
    position: relative;
    height: 56px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 20px;
    border-radius: 4px;
    cursor: pointer;

    &.active {
      background: #ecebfa;
      color: #4338ca;
    }
  }
  .role-info {
    display: flex;
    align-items: center;

    .icon {
      margin-right: 10px;
    }
  }
  .more {
    display: flex;
    align-items: center;
  }
  .role-add {
    width: 100%;
    margin-top: 20px;
  }
}
:deep() {
  .active-role {
    fill: #4338ca;
  }
}
.role-right {
  flex: 1;
  padding: 0 10px;
}
.tree-list {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  .tree-item {
    flex: 1;
    border-right: 1px solid #e4e7ec;
    padding: 0px 4px;
    text-align: center;
    margin-bottom: 5px;

    .tree-title {
      background: #f5f7fa;
      text-align: center;
      padding: 10px 0;
      margin-bottom: 12px;
    }
  }
}
.role-footer {
  text-align: left;
}
</style>
